//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#ifndef __OBJENUM_H__
#define __OBJENUM_H__

#include <linknode.h>
#include <elasys_server.h>
#include <interlocked.h>

class ObjectEnumeratorNode : public DLinkNode
{
public:
    virtual CARAPI_(IInterface *) GetObject() = 0;
};

class CObjectEnumerator : public IObjectEnumerator
{

public:
    CARAPI_(PInterface) Probe(
        /* [in]  */ REIID riid);

    CARAPI_(UInt32) AddRef();

    CARAPI_(UInt32) Release();

    CARAPI Aggregate(
        /* [in]  */ AggregateType type,
        /* [in]  */ PInterface pObject);

    CARAPI GetDomain(
        /* [out] */ PInterface *ppObject);

    CARAPI Current(
        /* [out] */ PInterface * ppObject);

    CARAPI MoveNext(
        /* [out] */ Boolean * pSucceeded);

    CARAPI Reset();

public:
    CObjectEnumerator(
        /* [in] */ DLinkNode * pListHead,
        /* [in] */ PVoid hListLock,
        /* [in] */ Int32 * pListState,
        /* [in] */ IInterface *pOwner);
    virtual ~CObjectEnumerator();

private:
    DLinkNode * m_pListHead;
    PVoid       m_hListLock;
    Int32     * m_pListState;

    DLinkNode * m_pCurrentNode;
    Int32       m_originalListState;

    IInterface   * m_pOwner;

private:
    Interlocked     m_cRef;
};
INLINE CObjectEnumerator::CObjectEnumerator(
    /* [in] */ DLinkNode *pListHead,
        /* [in] */ PVoid hListLock,
        /* [in] */ Int32 * pListState,
    /* [in] */ IInterface *pOwner)
{
    if (NULL != pOwner) {
        pOwner->AddRef();
    }
    m_pOwner = pOwner;

    m_pListHead  = pListHead;
    m_hListLock  = hListLock;
    m_pListState = pListState;

    m_pCurrentNode = m_pListHead;
    m_originalListState = *m_pListState;
}

INLINE CObjectEnumerator::~CObjectEnumerator()
{
    if (NULL != m_pOwner) {
        m_pOwner->Release();
    }
}

#endif //__OBJENUM_H__
